#include "LineItem.h"
#include "NodeInPort.h"
#include "NodeOutPort.h"
#include "AbstractManager.h"
#include "AbstractShapeItem.h"
#include "xMappingTree.h"
#include "xLink.h"
#include "xMappingNode.h"
#include <QPen>
#include <QBrush>
#include <QGraphicsScene>
#include <QGraphicsSceneMouseEvent>
#include <QPainter>
#include <QKeyEvent>
#include <QMenu>
#include <QIcon>

LineItem::LineItem(xMappingTree* xmt,NodeInPort* inPort,NodeOutPort* outPort,AbstractManager* manager)
	:Item(manager)
{
	if(xmt != NULL){
		if((inPort->getPortIOType()==NodePort::INPORT)&&(outPort->getPortIOType()==NodePort::OUTPORT)) {
			this->_link = xmt->create_link(outPort->getOutport(),inPort->getInport());
		}
	}
	this->_inport = inPort;
	this->_outport = outPort;

	//將自己加入2個port的linelist中
	inPort->getPortLineList().push_back(this);
	outPort->getPortLineList().push_back(this);

	this->setPen(QPen(Qt::white));
	this->setFlag(QGraphicsItem::ItemIsSelectable, true);
	this->setFlag(QGraphicsItem::ItemIsFocusable, true);
	this->updatePosition();
	this->setZValue( -10000 );
}

LineItem::~LineItem(void)
{
}

NodeInPort* LineItem::getInport()
{
	return this->_inport;
}

NodeOutPort* LineItem::getOutport()
{
	return this->_outport;
}

xLink* LineItem::getLink()
{
	return this->_link;
}

void LineItem::updatePosition()
{
	QPointF inportPoint  = QPointF(_inport->x()+ NodePort::RADIUS, _inport->y() + NodePort::RADIUS );
	QPointF outportPoint = QPointF(_outport->x() + NodePort::RADIUS, _outport->y() + NodePort::RADIUS );

	QLineF newLine(mapFromItem(_inport, inportPoint), mapFromItem(_outport, outportPoint));
	this->setLine(newLine);
}

void LineItem::paint( QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget )
{
	painter->setPen(this->pen());
	painter->drawLine(this->line());
	
}

QVariant LineItem::itemChange( GraphicsItemChange change, const QVariant &value )
{
	if ( change == QGraphicsItem::ItemSelectedHasChanged ) {
		if (this->scene()->selectedItems().contains(this)) {
			this->setPen(QPen(QBrush(QColor("#00FFFF")),2));
		} else {
			this->setPen(QPen(Qt::white));
		}
	}
	return QGraphicsItem::itemChange(change, value);
}

QPainterPath LineItem::shape() const
{
	QPainterPath path = QGraphicsLineItem::shape();
	//int extra = 3;
	//QVector<QPointF> points(4);

	//points.push_back(QPointF(line().p1().x()-extra, line().p1().y()-extra));
	//points.push_back(QPointF(line().p1().x()+extra, line().p1().y()+extra));
	//points.push_back(QPointF(line().p2().x()+extra, line().p2().y()+extra));
	//points.push_back(QPointF(line().p2().x()-extra, line().p2().y()-extra));
	//QPolygonF shape(points);
	//path.addPolygon(shape);
	return path;
}

QRectF LineItem::boundingRect() const
{
	qreal extra = (pen().width() + 0.5) / 2.0;

	QPointF topLeft(line().p1().x()-1, line().p1().y()-1);
	QPointF bottomRight(line().p2().x()+1, line().p2().y()+1);
	return QRectF(topLeft, bottomRight)
		.normalized()
		.adjusted(-extra, -extra, extra, extra);
}

void LineItem::keyPressEvent( QKeyEvent* event )
{
	QGraphicsLineItem::keyPressEvent(event);
}

void LineItem::removeFromScene() 
{
	this->_inport->removeLineFromVector(this);
	this->_outport->removeLineFromVector(this);
	_manager->deleteLine(this);
	this->scene()->removeItem(this);

}

void LineItem::remove()
{
	this->removeFromScene();

	// 假如 port 不是 fixed，則在刪除 LineItem 的同時也要將 port 刪除
	if ( !_inport->getParent()->getMappingNode()->getNodeTypePtr()->getInportFixed() ) {
		_inport->getParent()->deleteInPort(_inport);
	} else if ( !_outport->getParent()->getMappingNode()->getNodeTypePtr()->getOutportFixed() ) {
		_outport->getParent()->deleteOutPort(_outport);
	}

	delete this;
}

void LineItem::contextMenuEvent( QGraphicsSceneContextMenuEvent* event)
{
	this->setSelected(true);
	this->createActions();
	this->initMenu();
	_contextMenu->popup(event->screenPos());
}

void LineItem::createActions()
{
	_deleteAction = new QAction(QIcon(":/resource/cross-small-icon.png"), "Delete Link",this);
	connect(_deleteAction, SIGNAL(triggered()), this, SLOT(remove()));
}

void LineItem::initMenu()
{
	_contextMenu = new QMenu();
	_contextMenu->addAction(_deleteAction);
}
